import os
import time
import pyautogui
import cv2
import numpy as np
from loguru import logger
from PIL import Image
from datetime import datetime
import threading
import sys

# 配置日志
logger.add("logs/game_auto_{time}.log", rotation="500 MB", level="INFO")

class GameAutomation:
    def __init__(self):
        # 设置pyautogui的安全设置
        pyautogui.FAILSAFE = True
        pyautogui.PAUSE = 1.0
        
        # 初始化游戏窗口位置（后续需要根据实际情况调整）
        self.game_window = None
        
    def activate_game_window(self):
        """通过图像识别点击火影忍者字样激活游戏窗口"""
        try:
            title_pos, template_name, w, h = self.find_image_on_screen("templates/huoying_title.png", confidence=0.7)
            if title_pos:
                self.click_position(title_pos, template_name, w, h)
                time.sleep(1)
                return True
            else:
                logger.error("未找到火影忍者字样，无法激活窗口")
                return False
        except Exception as e:
            logger.error(f"激活游戏窗口时出错: {str(e)}")
            return False

    def find_image_on_screen(self, template_path, confidence=0.7):
        """
        在屏幕上查找指定图像，返回左上角位置、图片名、宽高
        
        Args:
            template_path: 模板图片路径
            confidence: 匹配置信度，默认0.7
            
        Returns:
            tuple: (位置, 图片名, 宽度, 高度)
        """
        try:
            # 获取屏幕截图
            screen = pyautogui.screenshot()
            screen_np = np.array(screen)
            screen_gray = cv2.cvtColor(screen_np, cv2.COLOR_BGR2GRAY)
            
            # 读取并预处理模板图片
            template = cv2.imread(template_path, 0)
            if template is None:
                logger.error(f"无法读取模板图片: {template_path}")
                return None, template_path, 0, 0
                
            # 检查模板图片尺寸
            h, w = template.shape
            screen_h, screen_w = screen_gray.shape
            if h > screen_h or w > screen_w:
                logger.error(f"模板图片尺寸({w}x{h})大于屏幕尺寸({screen_w}x{screen_h})")
                return None, template_path, 0, 0
            
            # 尝试多种预处理方法
            best_max_val = 0
            best_max_loc = None
            
            # 预处理方法列表
            preprocess_methods = [
                # 方法1: 自适应阈值
                lambda img: cv2.adaptiveThreshold(
                    img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                    cv2.THRESH_BINARY, 11, 2
                ),
                # 方法2: 高斯模糊+自适应阈值
                lambda img: cv2.adaptiveThreshold(
                    cv2.GaussianBlur(img, (3, 3), 0), 255,
                    cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2
                ),
                # 方法3: 简单二值化
                lambda img: cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1],
                # 方法4: 边缘检测
                lambda img: cv2.Canny(img, 100, 200),
                # 方法5: 原始灰度图
                lambda img: img
            ]
            
            # 对每种预处理方法进行尝试
            for i, preprocess in enumerate(preprocess_methods):
                try:
                    # 预处理模板和屏幕截图
                    template_processed = preprocess(template)
                    screen_processed = preprocess(screen_gray)
                    
                    # 模板匹配
                    result = cv2.matchTemplate(screen_processed, template_processed, cv2.TM_CCOEFF_NORMED)
                    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
                    
                    # 更新最佳结果
                    if max_val > best_max_val:
                        best_max_val = max_val
                        best_max_loc = max_loc
                        
                    logger.debug(f"预处理方法 {i+1} 匹配结果: {max_val:.2f}")
                    
                except Exception as e:
                    logger.debug(f"预处理方法 {i+1} 失败: {str(e)}")
                    continue
            
            # 使用最佳结果
            if best_max_val >= confidence:
                logger.debug(f"图片匹配成功: {template_path}, 最佳置信度: {best_max_val:.2f}")
                return best_max_loc, template_path, w, h
            else:
                logger.debug(f"图片匹配失败: {template_path}, 最佳置信度: {best_max_val:.2f}")
                return None, template_path, w, h
                
        except Exception as e:
            logger.error(f"查找图像时出错: {str(e)}")
            return None, template_path, 0, 0

    def click_position(self, position, template_name=None, w=0, h=0, duration=0.5):
        """点击指定图片中心位置，并打印图片名和位置"""
        try:
            if w > 0 and h > 0:
                center_x = position[0] + w // 2
                center_y = position[1] + h // 2
            else:
                center_x, center_y = position[0], position[1]
            pyautogui.click(center_x, center_y, duration=duration)
            if template_name:
                logger.info(f"点击图片: {template_name}，中心位置: ({center_x}, {center_y})")
            else:
                logger.info(f"点击位置: ({center_x}, {center_y})")
        except Exception as e:
            logger.error(f"点击操作失败: {str(e)}")

    def handle_timeout_popup(self, max_attempts=3, wait_time=2):
        """
        处理超时后的恭喜获得弹窗
        
        Args:
            max_attempts: 最大尝试次数
            wait_time: 每次尝试等待时间
            
        Returns:
            bool: 是否成功处理弹窗
        """
        for attempt in range(max_attempts):
            logger.info(f"第 {attempt + 1} 次尝试处理超时弹窗")
            
            # 尝试点击弹窗任意位置关闭
            pos, _, w, h = self.find_image_on_screen("templates/congrats_popup.png", confidence=0.6)
            if pos:
                # 点击弹窗中心位置
                center_x = pos[0] + w // 2
                center_y = pos[1] + h // 2
                pyautogui.click(center_x, center_y, duration=0.5)
                logger.info("成功点击关闭超时弹窗")
                time.sleep(wait_time)  # 等待弹窗消失
                return True
                
            # 如果没有找到弹窗，等待后重试
            time.sleep(wait_time)
            
        logger.warning("未能处理超时弹窗")
        return False

    def check_challenge_tickets(self, confidence=0.6):
        """
        检查是否还有挑战券
        
        Args:
            confidence: 匹配置信度
            
        Returns:
            bool: 是否还有挑战券
        """
        # 检查"挑战券不足"的提示
        pos, _, _, _ = self.find_image_on_screen("templates/no_tickets.png", confidence=confidence)
        if pos:
            logger.info("检测到挑战券不足")
            return False
            
        # 检查挑战券数量是否为0
        pos, _, _, _ = self.find_image_on_screen("templates/zero_tickets.png", confidence=confidence)
        if pos:
            logger.info("检测到挑战券数量为0")
            return False
            
        return True

    def click_image_center_with_retry(self, template_path, max_attempts=3, confidence=0.6, duration=0.5, wait_time=2):
        """
        查找图片并点击其中心位置，支持多次重试
        
        Args:
            template_path: 模板图片路径
            max_attempts: 最大尝试次数，默认3次
            confidence: 匹配置信度，默认0.6
            duration: 点击持续时间，默认0.5秒
            wait_time: 每次尝试之间的等待时间，默认2秒
            
        Returns:
            bool: 是否点击成功
        """
        for attempt in range(max_attempts):
            logger.info(f"第 {attempt + 1} 次尝试点击图片: {template_path}")
            
            # 每次尝试前等待界面加载
            time.sleep(wait_time)
            
            # 检查是否还有挑战券
            if not self.check_challenge_tickets():
                logger.info("挑战券已用完，任务完成")
                return False
            
            pos, _, w, h = self.find_image_on_screen(template_path, confidence=confidence)
            if pos:
                template = cv2.imread(template_path, 0)
                h, w = template.shape
                center_x = pos[0] + w // 2
                center_y = pos[1] + h // 2
                pyautogui.click(center_x, center_y, duration=duration)
                logger.info(f"点击成功: {template_path}，中心位置: ({center_x}, {center_y})")
                return True
            else:
                logger.warning(f"第 {attempt + 1} 次尝试未找到图片: {template_path}")
                if attempt < max_attempts - 1:
                    time.sleep(wait_time)  # 等待更长时间后重试
                    
        logger.error(f"经过 {max_attempts} 次尝试后仍未找到图片: {template_path}")
        return False

    def click_image_center(self, template_path, confidence=0.6, duration=0.5):
        """查找图片并点击其中心位置（使用重试机制）"""
        return self.click_image_center_with_retry(
            template_path=template_path,
            max_attempts=3,  # 默认尝试3次
            confidence=confidence,
            duration=duration,
            wait_time=2  # 增加等待时间到2秒
        )

    def search_with_movement(self, target_image, search_attempts=3, move_left_key='a', move_right_key='d', 
                           move_duration=1, wait_duration=1, confidence=0.7):
        """
        通用的循环搜索方法，通过左右移动来寻找目标图像
        
        Args:
            target_image: 要搜索的目标图像路径
            search_attempts: 搜索尝试次数，默认3次
            move_left_key: 向左移动的按键，默认'a'
            move_right_key: 向右移动的按键，默认'd'
            move_duration: 每次移动持续时间（秒），默认1秒
            wait_duration: 移动后等待时间（秒），默认1秒
            confidence: 图像匹配的置信度，默认0.7
            
        Returns:
            tuple: (是否找到目标, 目标位置, 图片宽度, 图片高度)
        """
        for attempt in range(search_attempts):
            logger.info(f"第 {attempt + 1} 次尝试寻找目标: {target_image}")
            
            # 1. 先向左移动寻找
            logger.info(f"按{move_left_key}键向左移动寻找目标")
            pyautogui.keyDown(move_left_key)
            time.sleep(move_duration)
            pyautogui.keyUp(move_left_key)
            time.sleep(wait_duration)
            
            # 检查是否找到目标
            target_pos, _, w, h = self.find_image_on_screen(target_image, confidence=confidence)
            if target_pos:
                logger.info("向左移动后找到目标")
                return True, target_pos, w, h
                
            # 2. 如果没找到，向右移动寻找
            logger.info(f"向左未找到目标，尝试向右移动")
            pyautogui.keyDown(move_right_key)
            time.sleep(move_duration)
            pyautogui.keyUp(move_right_key)
            time.sleep(wait_duration)
            
            # 再次检查是否找到目标
            target_pos, _, w, h = self.find_image_on_screen(target_image, confidence=confidence)
            if target_pos:
                logger.info("向右移动后找到目标")
                return True, target_pos, w, h
            
            logger.warning(f"第 {attempt + 1} 次尝试未找到目标")
            
            # 如果不是最后一次尝试，等待一下再继续
            if attempt < search_attempts - 1:
                time.sleep(wait_duration)
            
        logger.error(f"经过 {search_attempts} 次尝试后仍未找到目标")
        return False, None, 0, 0

def main():
    # 创建必要的目录
    os.makedirs("logs", exist_ok=True)
    os.makedirs("templates", exist_ok=True)
    
    # 初始化自动化对象
    game_auto = GameAutomation()
    
    # 导入任务模块
    from DailyTask.fengrao_task import FengraoTask
    from DailyTask.mijing_task import MijingTask
    
    # 创建任务实例
    fengrao = FengraoTask(game_auto)
    mijing = MijingTask(game_auto)
    
    # 确保游戏窗口处于激活状态
    if not game_auto.activate_game_window():
        logger.error("无法激活游戏窗口，任务终止")
        return
    time.sleep(1)  # 等待窗口激活

    # 执行丰饶之间任务（暂时注释掉，单独测试秘境挑战）
    # logger.info("开始执行丰饶之间任务")
    # fengrao_success = fengrao.execute()
    # if fengrao_success:
    #     logger.info("丰饶之间任务执行成功")
    # else:
    #     logger.error("丰饶之间任务执行失败")
    
    # 执行秘境挑战任务
    logger.info("开始执行秘境挑战任务")
    mijing_success = mijing.execute()
    if mijing_success:
        logger.info("秘境挑战任务执行成功")
    else:
        logger.error("秘境挑战任务执行失败，请检查日志")

if __name__ == "__main__":
    main() 